package com.photoslider.client;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.StackLayoutPanel;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwt.user.client.ui.VerticalPanel;

public class Photoslider implements EntryPoint
{

    VerticalPanel imagePlaceHolder = new VerticalPanel();
    Image biggerImage;
    Image selectedInSlider;

    int MAX_WIDTH = Window.getClientWidth() - Window.getScrollTop() - 15;
    int MAX_HEIGHT = Window.getClientHeight() - Window.getScrollLeft() - 15 - 100;
    int SLIDER_WIDTH = 350;
    int IMAGE_WIDTH = MAX_WIDTH - SLIDER_WIDTH;

    LoadingMask loadingMask = new LoadingMask("Loading Image, Please wait");
    private HorizontalPanel layout;

    List<RTImage> images = new ArrayList<Photoslider.RTImage>();
    private int currentIndex;
    private boolean slideshow = true;
    private StackLayoutPanel sliderPanel;
    private ToggleButton playBtn;
    private Timer timer;

    public void onModuleLoad()
    {
        Element loading = DOM.getElementById("loading");

        if ( loading != null )
            loading.setClassName("invisible");

        sliderPanel = new StackLayoutPanel(Unit.EM);
        sliderPanel.setPixelSize(SLIDER_WIDTH, MAX_HEIGHT);
        sliderPanel.setStyleName("slider");

        sliderPanel.add(getStudioPanel(), new HTML("<div class=\"header\">Our Studio</div>"), 3);
        sliderPanel.add(getPerformancePanel(), new HTML(
                        "<div class=\"header\">Past Performances</div>"), 3);
        sliderPanel.add(getTeachPanel(), new HTML("<div class=\"header\">What we teach</div>"), 3);

        layout = new HorizontalPanel();
        layout.setPixelSize(MAX_WIDTH, MAX_HEIGHT);
        layout.setStyleName("container");

        layout.add(sliderPanel);

        imagePlaceHolder.setWidth(IMAGE_WIDTH + "px");
        imagePlaceHolder.setHeight(MAX_HEIGHT + "px");
        imagePlaceHolder.setStyleName("imgPlace");

        layout.add(imagePlaceHolder);

        sliderPanel.addSelectionHandler(new SelectionHandler<Integer>() {

            @Override
            public void onSelection(SelectionEvent<Integer> event)
            {
                slideshow = false;
                playBtn.setValue(true);
            }
        });

        playBtn = new ToggleButton(new Image("images/pause.jpg"), new Image("images/play.jpg"),
                        new ClickHandler() {
                            @Override
                            public void onClick(ClickEvent event)
                            {
                                slideshow = !playBtn.isDown();
                                if ( slideshow && timer != null )
                                {
                                    timer.schedule(1);
                                }
                            }
                        });

        playBtn.setTitle("Play/Pause Slide show");
        playBtn.setStyleName("playBtn");
        imagePlaceHolder.add(playBtn);

        RTImage firtImage = images.get(0);
        currentIndex = 0;
        renderImage(firtImage.getImg(), firtImage.getFolder(), firtImage.getName());

        RootPanel.get("gallary").add(layout);
    }

    public VerticalPanel getPanel(List<String> values, String key)
    {
        VerticalPanel vLayout = new VerticalPanel();

        HorizontalPanel currentHLayout = null;
        for ( int i = 0; i < values.size(); i++ )
        {
            if ( i % 3 == 0 )
            {
                currentHLayout = new HorizontalPanel();
                currentHLayout.setHeight(105 + "px");
                currentHLayout.setSpacing(1);
                vLayout.add(currentHLayout);
            }

            currentHLayout.add(getSliderImage(key, values.get(i)));
        }

        vLayout.getElement().getStyle().setOverflowY(Overflow.SCROLL);
        vLayout.getElement().getStyle().setOverflowX(Overflow.HIDDEN);

        return vLayout;
    }

    private Image getSliderImage(final String folder, final String name)
    {
        final Image image = new Image("images/" + folder + "/small/" + name);

        images.add(new RTImage(folder, name, image));

        image.setStyleName("sliderimg");
        image.setTitle(name);

        image.addLoadHandler(new LoadHandler() {
            public void onLoad(LoadEvent event)
            {
                int dimention[] = scale(image, 100, 100);
                image.setPixelSize(dimention[1], dimention[0]);
            }
        });

        image.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event)
            {
                Image image = (Image) event.getSource();
                renderImage(image, folder, name);

                int index = 0;
                for ( RTImage img : images )
                {
                    if ( img.getFolder().equals(folder) && img.getName().equals(name) )
                    {
                        break;
                    }
                    index++;
                }

                currentIndex = index;
            }
        });

        return image;
    }

    private VerticalPanel getStudioPanel()
    {
        List<String> values = new ArrayList<String>();

        values.add("floorplan.jpg");
        values.add("fromMainRoad.jpg");
        values.add("danceFloor.jpg");
        values.add("danceFloor2.jpg");
        values.add("strechingPlace.jpg");
        values.add("personalTrainingRoom.jpg");
        values.add("musicRoom.jpg");
        values.add("yogaRoom.jpg");
        values.add("frontOffice.jpg");
        values.add("pantry.jpg");
        values.add("entrance.jpg");
        values.add("costumeRoom.jpg");

        return getPanel(values, "studio");
    }

    private VerticalPanel getPerformancePanel()
    {
        List<String> values = new ArrayList<String>();

        values.add("classical.jpg");
        values.add("malabarGold.jpg");
        values.add("bollywood.jpg");
        values.add("johnTeachingToSchoolKids.jpg");
        values.add("countryClub.jpg");
        values.add("dancePerformance.jpg");
        values.add("dancePerformanceBigStage.jpg");
        values.add("schoolDance.jpg");
        values.add("freeStyle.jpg");
        values.add("garbaChoreography.jpg");
        values.add("kidsChoreography.jpg");
        values.add("kidsIndipendenceDayChoreography.jpg");
        values.add("justDance.jpg");
        values.add("choreography.jpg");
        values.add("salsa.jpg");
        values.add("bollywoodPerformance.jpg");
        values.add("folkChoreography.jpg");
        values.add("mimic.jpg");

        return getPanel(values, "performance");
    }

    private VerticalPanel getTeachPanel()
    {
        List<String> values = new ArrayList<String>();

        values.add("bollywood.jpg");
        values.add("freestyle.jpg");
        values.add("western.jpg");
        values.add("beboying.jpg");
        values.add("ballet.jpg");
        values.add("hiphop.jpg");
        values.add("music.jpg");
        values.add("painting.jpg");
        values.add("salsa.jpg");
        values.add("aerobics.jpg");
        values.add("yoga.jpg");

        return getPanel(values, "teach");
    }

    private void renderImage(Image image, String folder, String name)
    {
        image.addStyleName("imgselected");

        String clickedImage = image.getUrl();

        if ( biggerImage != null )
        {
            biggerImage.removeFromParent();
            loadingMask.show(imagePlaceHolder);
        }

        int indexOf = Folders.folders.indexOf(folder);
        if ( indexOf != sliderPanel.getVisibleIndex() )
        {
            sliderPanel.showWidget(indexOf);
        }

        if ( selectedInSlider != null )
        {
            selectedInSlider.removeStyleName("imgselected");
        }

        biggerImage = new Image(clickedImage.replace("small", "actual"));
        biggerImage.setVisible(false);
        selectedInSlider = image;

        imagePlaceHolder.setHorizontalAlignment(HasAlignment.ALIGN_CENTER);
        imagePlaceHolder.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE);

        imagePlaceHolder.add(biggerImage);
        imagePlaceHolder.setTitle(name);

        biggerImage.addLoadHandler(new LoadHandler() {

            public void onLoad(LoadEvent event)
            {
                loadingMask.hide();

                biggerImage.setVisible(true);

                int[] dimention = scale(biggerImage, MAX_HEIGHT, IMAGE_WIDTH);

                biggerImage.setPixelSize(dimention[1], dimention[0]);
                imagePlaceHolder.setPixelSize(IMAGE_WIDTH, MAX_HEIGHT);
                layout.setPixelSize(MAX_WIDTH, MAX_HEIGHT);

                timer = new Timer() {
                    public void run()
                    {
                        if ( slideshow )
                        {
                            RTImage rtImage = images.get(++currentIndex % images.size());
                            renderImage(rtImage.getImg(), rtImage.getFolder(), rtImage.getName());
                        }
                    }
                };

                timer.schedule(2000);
            }
        });
    }

    private int[] scale(Image img, int maxHeight, int maxWidth)
    {
        int height = img.getOffsetHeight();
        int width = img.getOffsetWidth();

        int finalHeight = height;
        int finalWidth = width;

        double ratio = 0.0;

        if ( width > maxWidth )
        {
            ratio = (double) maxWidth / width;

            finalWidth = maxWidth;
            finalHeight = (int) (height * ratio);

            height = (int) (height * ratio);
            width = (int) (width * ratio);
        }

        if ( height > maxHeight )
        {
            ratio = (double) maxHeight / height;

            finalHeight = maxHeight;
            finalWidth = (int) (width * ratio);

            width = (int) (width * ratio);
        }

        return new int[] { finalHeight, finalWidth };
    }

    @SuppressWarnings("unused")
    private static class RTImage
    {
        private String name;
        private String folder;
        private Image img;

        public RTImage(String folder, String name, Image img)
        {
            super();
            this.folder = folder;
            this.name = name;
            this.img = img;
        }

        public String getFolder()
        {
            return folder;
        }

        public void setFolder(String folder)
        {
            this.folder = folder;
        }

        public String getName()
        {
            return name;
        }

        public void setName(String name)
        {
            this.name = name;
        }

        public Image getImg()
        {
            return img;
        }

        public void setImg(Image img)
        {
            this.img = img;
        }

    }
}
